home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Backups / Tabu / tabu.c < prev    next >
C/C++ Source or Header  |  1996-09-26  |  31KB  |  1,129 lines

  1. #include "exec/types.h"
  2. #include "exec/ports.h"
  3. #include "exec/libraries.h"
  4. #include "exec/io.h"
  5. #include "exec/tasks.h"
  6. #include "exec/execbase.h"
  7. #include "libraries/dos.h"
  8. #include "libraries/dosextens.h"
  9. #include "workbench/workbench.h"
  10. #include "workbench/startup.h"
  11. #include "devices/scsidisk.h"
  12.  
  13. #include "stdio.h"
  14. #include "time.h"
  15. #include "functions.h"
  16.  
  17. #define RZ_BMAGIC 0x525a4d42
  18. #define RZ_CMAGIC 0x525a4d43
  19. #define RZ_SCSI "HardFrame.device"
  20. #define RZ_DISK 000
  21. #define RZ_TAPE 001
  22. #define RZ_BLKS 128
  23. #define RZ_BYTS 512
  24. #define RZ_IOR struct IORequest
  25.  
  26. extern struct ExecBase *SysBase;
  27. struct Library *IconBase;
  28.  
  29. void dsk2tap();
  30. void tapelst();
  31. void tap2dsk();
  32. long bk_create(char *name);
  33. void bk_d2t();
  34. void bk_extract();
  35. void bk_t2d();
  36. long bk_write(struct FileInfoBlock *fib);
  37. long dk_capacity();
  38. long dk_close();
  39. long dk_init();
  40. long dk_read(long lba,long len);
  41. long dk_write(long lba,long len);
  42. void tmconv(struct DateStamp *date,char *dstr,char *tstr);
  43. long tp_close();
  44. long tp_eof();
  45. long tp_init();
  46. long tp_read(long len);
  47. long tp_rewind();
  48. long tp_sense();
  49. long tp_write(long len);
  50.  
  51. long disk = RZ_DISK;
  52. long tape = RZ_TAPE;
  53. char scsi[] = RZ_SCSI;
  54.  
  55. long nest;
  56. char refname[256];
  57. UBYTE dkcmd[32];
  58. UBYTE tpcmd[32];
  59. UWORD data[RZ_BLKS * RZ_BYTS / 2];
  60. ULONG *ldata = (ULONG *)data;
  61. UBYTE *bdata = (UBYTE *)data;
  62. UBYTE *dptr;
  63.  
  64. struct MsgPort dkmp = {{0,0,NT_MSGPORT,0,0},0,SIGB_SINGLE,0,{0,0,0,0,0}};
  65. struct IOStdReq dkior = {{{0,0,NT_MESSAGE,0,0},&dkmp,0},0,0,0,0,0,0,0,0,0};
  66. struct SCSICmd dksc;
  67. struct MsgPort tpmp = {{0,0,NT_MSGPORT,0,0},0,SIGB_SINGLE,0,{0,0,0,0,0}};
  68. struct IOStdReq tpior = {{{0,0,NT_MESSAGE,0,0},&tpmp,0},0,0,0,0,0,0,0,0,0};
  69. struct SCSICmd tpsc;
  70. struct WBStartup *wbsm;
  71. struct WBArg *wba;
  72. struct DiskObject *dobj;
  73.  
  74. union FHeader
  75. {
  76.    struct FHBlock
  77.    {
  78.       ULONG magic;
  79.       long nest;
  80.       struct FileInfoBlock fib;
  81.    } fhb;
  82.    UBYTE fhbuf[sizeof(struct FHBlock)];
  83. } fhdr;
  84. struct FileInfoBlock *gfib = &(fhdr.fhb.fib);
  85.  
  86. /* ---------------------------------------------------------------------- */
  87. main(long argc, char **argv)
  88. {
  89.    long i;
  90.    long err;
  91.    long func;
  92.    char *cptr;
  93.    struct FileLock *olddir;
  94.  
  95.    fprintf(stderr,"\ntabu -  QIC tape backup utility\n");
  96.    fprintf(stderr,"Copyright 1990 - Roy C. Sigsbey\n\n");
  97.    if (argc == 0)
  98.    {
  99.       if ((IconBase = OpenLibrary("icon.library",0)) == NULL)
  100.       {
  101.          fprintf(stderr,"tabu: Icon library open failed, bye\n");
  102.          fprintf(stderr,"tabu finished, Press RETURN when ready.\n");
  103.          getchar();
  104.          exit(1);
  105.       }
  106.       else
  107.       {
  108.          wbsm = (struct WBStartup *)argv;
  109.          wba = wbsm->sm_ArgList;
  110.          olddir = CurrentDir((struct FileLock *)wba->wa_Lock);
  111.          dobj = GetDiskObject(wba->wa_Name);
  112.          err = 0;
  113.          if ((cptr = FindToolType(dobj->do_ToolTypes,"OPER")) != NULL)
  114.          {
  115.             switch(cptr[0])
  116.             {
  117.                case 'B':
  118.                case 'b':
  119.                   func = 1;
  120.                   break;
  121.                case 'C':
  122.                case 'c':
  123.                   func = 2;
  124.                   break;
  125.                case 'L':
  126.                case 'l':
  127.                   func = 3;
  128.                   break;
  129.                case 'R':
  130.                case 'r':
  131.                   func = 4;
  132.                   break;
  133.                case 'X':
  134.                case 'x':
  135.                   func = 5;
  136.                   break;
  137.                default:
  138.                   err = 1;
  139.                   break;
  140.             }
  141.          }
  142.          else err = 1;
  143.          if ((cptr = FindToolType(dobj->do_ToolTypes,"NAME")) != NULL)
  144.             strcpy(refname,cptr);
  145.          else refname[0] = '\0';
  146.          if ((cptr = FindToolType(dobj->do_ToolTypes,"LIST")) != NULL)
  147.          {
  148.             if (freopen(cptr,"w",stdout) == NULL) err = 1;
  149.          }
  150.          if ((cptr = FindToolType(dobj->do_ToolTypes,"SCSI")) != NULL)
  151.          {
  152.             strcpy(scsi,cptr);
  153.          }
  154.          if ((cptr = FindToolType(dobj->do_ToolTypes,"DISK")) != NULL)
  155.          {
  156.             if (sscanf(cptr,"%3d",&disk) != 1) err = 1;
  157.          }
  158.          if ((cptr = FindToolType(dobj->do_ToolTypes,"TAPE")) != NULL)
  159.          {
  160.             if (sscanf(cptr,"%3d",&tape) != 1) err = 1;
  161.          }
  162.          CurrentDir(olddir);
  163.          CloseLibrary(IconBase);
  164.       }
  165.    }
  166.    else
  167.    {
  168.       err = 0;
  169.       func = 0;
  170.       refname[0] = '\0';
  171.       for (i = 1; i < argc; i++)
  172.       {
  173.          if (argv[i][0] == '-')
  174.          {
  175.             switch (argv[i][1])
  176.             {
  177.                case 'B':
  178.                case 'b':
  179.                   func = 1;
  180.                   break;
  181.                case 'C':
  182.                case 'c':
  183.                   func = 2;
  184.                   break;
  185.                case 'D':
  186.                case 'd':
  187.                   if (sscanf(&(argv[i][2]),"%3d",&disk) != 1) err = 1;
  188.                   break;
  189.                case 'L':
  190.                case 'l':
  191.                   func = 3;
  192.                   break;
  193.                case 'R':
  194.                case 'r':
  195.                   func = 4;
  196.                   break;
  197.                case 'S':
  198.                case 's':
  199.                   strcpy(scsi,&(argv[i][2]));
  200.                   break;
  201.                case 'T':
  202.                case 't':
  203.                   if (sscanf(&(argv[i][2]),"%3d",&tape) != 1) err = 1;
  204.                   break;
  205.                case 'X':
  206.                case 'x':
  207.                   func = 5;
  208.                   break;
  209.                default:
  210.                   err = 1;
  211.                   break;
  212.             }
  213.          }
  214.          else strcpy(refname,argv[i]);
  215.       }
  216.    }
  217.    if (err != 0) func = 0;
  218.    switch (func)
  219.    {
  220.       case 1:
  221.          bk_d2t();
  222.          break;
  223.       case 2:
  224.          dsk2tap();
  225.          break;
  226.       case 3:
  227.          tapelst();
  228.          break;
  229.       case 4:
  230.          bk_t2d();
  231.          break;
  232.       case 5:
  233.          tap2dsk();
  234.          break;
  235.       default:
  236.          fprintf(stderr,
  237.             "usage: tabu [-ddsk] [-sscsi] [-ttap] -b|c|l|r|x [name]\n");
  238.          fprintf(stderr,"     -b = backup by blocks to tape\n");
  239.          fprintf(stderr,"     -c = create backup to tape\n");
  240.          fprintf(stderr,"     -d = dsk is scsi address for disk\n");
  241.          fprintf(stderr,"     -l = list tape contents\n");
  242.          fprintf(stderr,"     -r = restore by blocks from tape\n");
  243.          fprintf(stderr,"     -s = scsi is scsi device name\n");
  244.          fprintf(stderr,"     -t = tap is scsi address for tape\n");
  245.          fprintf(stderr,"     -x = extract from tape\n");
  246.          fprintf(stderr,"   name = reference name (req'd - c or x)\n");
  247.          fprintf(stderr,"tabu.info ToolTypes may be set as follows:\n");
  248.          fprintf(stderr,"   OPER=B      backup\n");
  249.          fprintf(stderr,"   OPER=C      create\n");
  250.          fprintf(stderr,"   OPER=L      list\n");
  251.          fprintf(stderr,"   OPER=R      restore\n");
  252.          fprintf(stderr,"   OPER=X      extract\n");
  253.          fprintf(stderr,"   NAME=name   reference name (req'd - C or X)\n");
  254.          fprintf(stderr,"   LIST=name   list to file or printer\n");
  255.          fprintf(stderr,"   DISK=nnn    disk scsi address\n");
  256.          fprintf(stderr,"   TAPE=nnn    tape scsi address\n");
  257.          fprintf(stderr,"   SCSI=name   scsi device name\n");
  258.    }
  259.    fprintf(stderr,"tabu finished, Press RETURN when ready.\n");
  260.    getchar();
  261.    exit(0);
  262. }
  263. /* ---------------------------------------------------------------------- */
  264. void dsk2tap()
  265. {
  266.    time_t timer;
  267.  
  268.    if (strlen(refname) == 0)
  269.    {
  270.       fprintf(stderr,"tabu: reference name required for create\n");
  271.       return;
  272.    }
  273.    nest = 0;
  274.    dptr = bdata;
  275.    if (tp_init()) return;
  276.    if (bdata[8] & 0x10)
  277.    {
  278.       fprintf(stderr,"tabu: tape is write protected\n");
  279.       tp_close();
  280.       return;
  281.    }
  282.    time(&timer);
  283.    printf("\ntabu: backup %s\n",ctime(&timer));
  284.    if (bk_create(refname))
  285.    {
  286.       tp_close();
  287.       return;
  288.    }
  289.    if (dptr != bdata)
  290.    {
  291.       if (tp_write(((long)(dptr - bdata) / RZ_BYTS)))
  292.       {
  293.          tp_close();
  294.          return;
  295.       }
  296.    }
  297.    tp_eof();
  298.    tp_close();
  299.    return;
  300. }
  301. /* ---------------------------------------------------------------------- */
  302. void tapelst()
  303. {
  304.    long i;
  305.    long first_time;
  306.    char datestr[16];
  307.    char timestr[16];
  308.  
  309.    if (tp_init()) return;
  310.    first_time = 1;
  311.    tpsc.scsi_Actual = RZ_BYTS * RZ_BLKS;
  312.    while (tpsc.scsi_Actual == (RZ_BYTS * RZ_BLKS))
  313.    {
  314.       if (tp_read(RZ_BLKS))
  315.       {
  316.          tp_close();
  317.          return;
  318.       }
  319.       if (first_time)
  320.       {
  321.          if ((bdata[0] != 'R') || (bdata[1] != 'Z') || (bdata[2] != 'M'))
  322.          {
  323.             fprintf(stderr,"tabu: tape is not a tabu backup\n");
  324.             break;
  325.          }
  326.          if (bdata[3] == 'B')
  327.          {
  328.             fprintf(stderr,"tabu: tape is a tabu disk image backup\n");
  329.             fprintf(stderr,"   backup date = %s\n",&(bdata[4]));
  330.             break;
  331.          }
  332.          first_time = 0;
  333.       }
  334.       for (dptr = bdata; dptr < (bdata + tpsc.scsi_Actual); dptr += RZ_BYTS)
  335.       {
  336.          if ((dptr[0] == 'R') && (dptr[1] == 'Z') && (dptr[2] == 'M') &&
  337.              (dptr[3] == 'C'))
  338.          {
  339.             for (i = 0; i < sizeof(struct FHBlock); i++)
  340.                fhdr.fhbuf[i] = dptr[i];
  341.             tmconv(&(gfib->fib_Date),datestr,timestr);
  342.             printf("l - %08x %s %s %9d ",gfib->fib_Protection,datestr,
  343.                timestr,gfib->fib_Size);
  344.             for (i = 0; i < fhdr.fhb.nest; i++)
  345.                printf("|  ");
  346.             printf("%s\n",gfib->fib_FileName);
  347.          }
  348.       }
  349.    }
  350.    tp_close();
  351.    return;
  352. }
  353. /* ---------------------------------------------------------------------- */
  354. void tap2dsk()
  355. {
  356.    struct FileInfoBlock *fib;
  357.    struct FileLock *fl,*ofl;
  358.  
  359. /* access refname which must be a directory or disk */
  360.    if (strlen(refname) == 0)
  361.    {
  362.       fprintf(stderr,"tabu: reference name required for extract\n");
  363.       return;
  364.    }
  365.    fib = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0);
  366.    if (fib == NULL)
  367.    {
  368.       fprintf(stderr,"tabu: tap2dsk, fib allocation failed\n");
  369.       return;
  370.    }
  371.    if ((fl = Lock(refname,ACCESS_READ)) == NULL)
  372.    {
  373.       FreeMem(fib,sizeof(struct FileInfoBlock));
  374.       fprintf(stderr,"tabu: tap2dsk, Lock of %s failed\n",refname);
  375.       return;
  376.    }
  377.    if (!Examine(fl,fib))
  378.    {
  379.       UnLock(fl);
  380.       FreeMem(fib,sizeof(struct FileInfoBlock));
  381.       fprintf(stderr,"tabu: tap2dsk, Examine of %s failed\n",refname);
  382.       return;
  383.    }
  384.    if(fib->fib_DirEntryType <= 0)
  385.    {
  386.       UnLock(fl);
  387.       FreeMem(fib,sizeof(struct FileInfoBlock));
  388.       fprintf(stderr,"tabu: reference for extract must be a directory\n");
  389.       return;
  390.    }
  391.  
  392. /* initialize tape */
  393.    if (tp_init())
  394.    {
  395.       UnLock(fl);
  396.       FreeMem(fib,sizeof(struct FileInfoBlock));
  397.       return;
  398.    }
  399.  
  400. /* cd to refname and ready to extract tape contents into it */
  401.    ofl = CurrentDir(fl);
  402.    tpsc.scsi_Actual = RZ_BYTS * RZ_BLKS;
  403.    dptr = bdata + tpsc.scsi_Actual;
  404.  
  405. /* extract tape contents */
  406.    nest = 0;
  407.    bk_extract();
  408.  
  409. /* done - cd back to where we were before */
  410.    ofl = CurrentDir(ofl);
  411.    UnLock(fl);
  412.    FreeMem(fib,sizeof(struct FileInfoBlock));
  413.    tp_close();
  414.    return;
  415. }
  416. /* ---------------------------------------------------------------------- */
  417. long bk_create(char *name)
  418. {
  419.    long i;
  420.    long fin;
  421.    struct FileInfoBlock *fib;
  422.    struct FileLock *fl,*ofl;
  423.    char datestr[16];
  424.    char timestr[16];
  425.  
  426. /* access the named object */
  427.    fib = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),0);
  428.    if (fib == NULL)
  429.    {
  430.       fprintf(stderr,"tabu: bk_create, fib allocation failed\n");
  431.       return 1;
  432.    }
  433.    if ((fl = Lock(name,ACCESS_READ)) == NULL)
  434.    {
  435.       fprintf(stderr,"tabu: bk_create, Lock of %s failed\n",name);
  436.       FreeMem(fib,sizeof(struct FileInfoBlock));
  437.       return 1;
  438.    }
  439.    if (!Examine(fl,fib))
  440.    {
  441.       fprintf(stderr,"tabu: bk_create, Examine of %s failed\n",name);
  442.       UnLock(fl);
  443.       FreeMem(fib,sizeof(struct FileInfoBlock));
  444.       return 1;
  445.    }
  446.  
  447. /* Don't write disk device block to tape */
  448.    if (name[strlen(name) - 1] == ':') nest--;
  449.    else
  450.    {
  451.  
  452. /* print line describing current object name */
  453.       tmconv(&(fib->fib_Date),datestr,timestr);
  454.       printf("c - %08x %s %s %9d ",fib->fib_Protection,datestr,timestr,
  455.          fib->fib_Size);
  456.       for (i = 0; i < nest; i++)
  457.          printf("|  ");
  458.       printf("%s\n",fib->fib_FileName);
  459.  
  460. /* build tape image of FileInfoBlock and write it to tape */
  461.       fhdr.fhb.magic = RZ_CMAGIC;
  462.       fhdr.fhb.nest = nest;
  463.       gfib->fib_DiskKey = fib->fib_DiskKey;
  464.       gfib->fib_DirEntryType = fib->fib_DirEntryType;
  465.       strcpy(gfib->fib_FileName,fib->fib_FileName);
  466.       for (i = (strlen(gfib->fib_FileName) + 1); i < 108; i++)
  467.          gfib->fib_FileName[i] = '\0';
  468.       gfib->fib_Protection = fib->fib_Protection;
  469.       gfib->fib_EntryType = fib->fib_EntryType;
  470.       gfib->fib_Size = fib->fib_Size;
  471.       gfib->fib_NumBlocks = fib->fib_NumBlocks;
  472.       gfib->fib_Date.ds_Days = fib->fib_Date.ds_Days;
  473.       gfib->fib_Date.ds_Minute = fib->fib_Date.ds_Minute;
  474.       gfib->fib_Date.ds_Tick = fib->fib_Date.ds_Tick;
  475.       for (i = 0; i < 80; i++)
  476.          gfib->fib_Comment[i] = fib->fib_Comment[i];
  477.       for (i = 0; i < 36; i++)
  478.          gfib->fib_Reserved[i] = fib->fib_Reserved[i];
  479.       for (i = 0; i < RZ_BYTS; i++)
  480.       {
  481.          if (i < sizeof(struct FHBlock)) dptr[i] = fhdr.fhbuf[i];
  482.          else dptr[i] = 0x00;
  483.       }
  484.       dptr += RZ_BYTS;
  485.       if (dptr >= (bdata + (RZ_BLKS * RZ_BYTS)))
  486.       {
  487.          dptr = bdata;
  488.          if (tp_write(RZ_BLKS))
  489.          {
  490.             UnLock(fl);
  491.             FreeMem(fib,sizeof(struct FileInfoBlock));
  492.             return 1;
  493.          }
  494.       }
  495.    }
  496.  
  497. /* if object is a directory: */
  498.    if(fib->fib_DirEntryType > 0)
  499.    {
  500.       nest++;
  501.       ofl = CurrentDir(fl);
  502.       fin = 0;
  503.       while (fin == 0)
  504.       {
  505.          if (ExNext(fl,fib))
  506.          {
  507.             if (bk_create(fib->fib_FileName)) fin = 2;
  508.          }
  509.          else
  510.          {
  511.             if ((fin = IoErr()) != ERROR_NO_MORE_ENTRIES)
  512.             {
  513.                fprintf(stderr,"tabu: ExNext error = %d\n",fin);
  514.                fin = 2;
  515.             }
  516.             else fin = 1;
  517.          }
  518.       }
  519.       ofl = CurrentDir(ofl);
  520.       nest--;
  521.    }
  522.  
  523. /* else it is a file: */
  524.    else
  525.    {
  526.       fin = 1;
  527.       if (bk_write(fib)) fin++;
  528.    }
  529.  
  530. /* done with this object */
  531.    UnLock(fl);
  532.    FreeMem(fib,sizeof(struct FileInfoBlock));
  533.    return --fin;
  534. }
  535. /* ---------------------------------------------------------------------- */
  536. void bk_d2t()
  537. {
  538.    long size;
  539.    time_t timer;
  540.  
  541.    if (dk_init()) return;
  542.    if (tp_init())
  543.    {
  544.       dk_close();
  545.       return;
  546.    }
  547.    ldata[0] = RZ_BMAGIC;
  548.    time(&timer);
  549.    strcpy(&(bdata[4]),ctime(&timer));
  550.    if (tp_write(1))
  551.    {
  552.       tp_close();
  553.       dk_close();
  554.       return;
  555.    }
  556.    dksc.scsi_Actual = RZ_BYTS * RZ_BLKS;
  557.    for (size = 0; dksc.scsi_Actual == (RZ_BYTS * RZ_BLKS);
  558.       size += dksc.scsi_Actual)
  559.    {
  560.       if (dk_read((size / RZ_BYTS),RZ_BLKS)) break;
  561.       if (tp_write(dksc.scsi_Actual / RZ_BYTS)) break;
  562.    }
  563.    fprintf(stderr,"tabu: backup bytes = %d\n",size);
  564.    tp_eof();
  565.    tp_close();
  566.    dk_close();
  567. }
  568. /* ---------------------------------------------------------------------- */
  569. void bk_extract()
  570. {
  571.    long i;
  572.    long wrsz;
  573.    long timer;
  574.    char namestr[256];
  575.    char datestr[16];
  576.    char timestr[16];
  577.    struct FileLock *fl,*ofl;
  578.    struct FileHandle *fhndl;
  579.  
  580. /* normal exit is nest level change or end of tape */
  581.    while (1)
  582.    {
  583.  
  584. /* ready next data block from tape */
  585.       if (dptr >= bdata + tpsc.scsi_Actual)
  586.       {
  587.          if (tpsc.scsi_Actual != (RZ_BYTS * RZ_BLKS)) return;
  588.          if (tp_read(RZ_BLKS)) return;
  589.          dptr = bdata;
  590.       }
  591.  
  592. /* copy tape block to header area */
  593.       for (i = 0; i < sizeof(struct FHBlock); i++)
  594.          fhdr.fhbuf[i] = dptr[i];
  595.  
  596. /* this had better be header block, not data block */
  597.       if (fhdr.fhb.magic != RZ_CMAGIC)
  598.       {
  599.          fprintf(stderr,"tabu: tape is not tabu file image backup\n");
  600.          return;
  601.       }
  602.  
  603. /* this item is a sibling to a higher nest level (lower number) */
  604.       if (fhdr.fhb.nest < nest) return;
  605.  
  606. /* we should never have a nest jump greater than one */
  607.       if (fhdr.fhb.nest > nest)
  608.       {
  609.          fprintf(stderr,"tabu: bk_extract, header nest error\n");
  610.          return;
  611.       }
  612.  
  613. /* List header block being processed */
  614.       tmconv(&(gfib->fib_Date),datestr,timestr);
  615.       printf("x - %08x %s %s %9d ",gfib->fib_Protection,datestr,timestr,
  616.          gfib->fib_Size);
  617.       for (i = 0; i < fhdr.fhb.nest; i++)
  618.          printf("|  ");
  619.       printf("%s\n",gfib->fib_FileName);
  620.  
  621. /* set up name for SetDate fexecl call */
  622.       sprintf(namestr,"\"%s\"",gfib->fib_FileName);
  623.  
  624. /* Directory header block processing */
  625.       if(gfib->fib_DirEntryType > 0)
  626.       {
  627.          dptr += RZ_BYTS;
  628.          if ((fl = Lock(gfib->fib_FileName,ACCESS_READ)) == NULL)
  629.          {
  630.             if ((fl = CreateDir(gfib->fib_FileName)) == NULL)
  631.             {
  632.                fprintf(stderr,"tabu: CreateDir failed for %s\n",
  633.                   gfib->fib_FileName);
  634.                dptr = bdata;
  635.                tpsc.scsi_Actual = 0;
  636.                return;
  637.             }
  638.          }
  639.          ofl = CurrentDir(fl);
  640.          nest++;
  641.          bk_extract();
  642.          nest--;
  643.          ofl = CurrentDir(ofl);
  644.          UnLock(fl);
  645.          SetProtection(gfib->fib_FileName,gfib->fib_Protection);
  646.          SetComment(gfib->fib_FileName,gfib->fib_Comment);
  647.          fexecl("SetDate","SetDate",namestr,datestr,timestr,NULL);
  648.       }
  649.  
  650. /* File block(s) processing */
  651.       else
  652.       {
  653.  
  654. /* File header block */
  655.          if ((dptr += RZ_BYTS) >= bdata + tpsc.scsi_Actual)
  656.          {
  657.             if (tpsc.scsi_Actual != (RZ_BYTS * RZ_BLKS))
  658.             {
  659.                fprintf(stderr,
  660.                   "tabu: extract, tape eof before file size satisfied\n");
  661.                return;
  662.             }
  663.             if (tp_read(RZ_BLKS)) return;
  664.             dptr = bdata;
  665.          }
  666.          if ((fl = Lock(gfib->fib_FileName,ACCESS_WRITE)) == NULL)
  667.          {
  668.             if ((fhndl = Open(gfib->fib_FileName,MODE_NEWFILE))
  669.                == NULL)
  670.             {
  671.                fprintf(stderr,"tabu: bk_extract, Open failed for %s\n",
  672.                   gfib->fib_FileName);
  673.                dptr = bdata;
  674.                tpsc.scsi_Actual = 0;
  675.                return;
  676.             }
  677.          }
  678.          else
  679.          {
  680.             UnLock(fl);
  681.             if ((fhndl = Open(gfib->fib_FileName,MODE_READWRITE))
  682.                == NULL)
  683.             {
  684.                fprintf(stderr,"tabu: bk_extract, Open failed for %s\n",
  685.                   gfib->fib_FileName);
  686.                dptr = bdata;
  687.                tpsc.scsi_Actual = 0;
  688.                return;
  689.             }
  690.          }
  691.  
  692. /* File data block(s) */
  693.          for (i = gfib->fib_Size; i > 0; i -= RZ_BYTS)
  694.          {
  695.             if (i >= RZ_BYTS) wrsz = RZ_BYTS;
  696.             else wrsz = i;
  697.             if (Write(fhndl,(char *)dptr,wrsz) != wrsz)
  698.             {
  699.                fprintf(stderr,"tabu: bk_extract, file data write failed\n");
  700.                Close(fhndl);
  701.                SetProtection(gfib->fib_FileName,gfib->fib_Protection);
  702.                SetComment(gfib->fib_FileName,gfib->fib_Comment);
  703.                fexecl("SetDate","SetDate",namestr,datestr,timestr,NULL);
  704.                dptr = bdata;
  705.                tpsc.scsi_Actual = 0;
  706.                return;
  707.             }
  708.             if ((dptr += RZ_BYTS) >= (bdata + tpsc.scsi_Actual))
  709.             {
  710.                if (tpsc.scsi_Actual != (RZ_BYTS * RZ_BLKS))
  711.                {
  712.                   if ((i - RZ_BYTS) > 0) fprintf(stderr,
  713.                      "tabu: extract, tape eof before file size satisfied\n");
  714.                   Close(fhndl);
  715.                   SetProtection(gfib->fib_FileName,gfib->fib_Protection);
  716.                   SetComment(gfib->fib_FileName,gfib->fib_Comment);
  717.                   fexecl("SetDate","SetDate",namestr,datestr,timestr,NULL);
  718.                   return;
  719.                }
  720.                if (tp_read(RZ_BLKS))
  721.                {
  722.                   Close(fhndl);
  723.                   SetProtection(gfib->fib_FileName,gfib->fib_Protection);
  724.                   SetComment(gfib->fib_FileName,gfib->fib_Comment);
  725.                   fexecl("SetDate","SetDate",namestr,datestr,timestr,NULL);
  726.                   return;
  727.                }
  728.                dptr = bdata;
  729.             }
  730.          }
  731.          Close(fhndl);
  732.          SetProtection(gfib->fib_FileName,gfib->fib_Protection);
  733.          SetComment(gfib->fib_FileName,gfib->fib_Comment);
  734.          fexecl("SetDate","SetDate",namestr,datestr,timestr,NULL);
  735.       }
  736.    }
  737. }
  738. /* ---------------------------------------------------------------------- */
  739. void bk_t2d()
  740. {
  741.    long size;
  742.  
  743.    if (tp_init()) return;
  744.    if (tp_read(1))
  745.    {
  746.       tp_close();
  747.       return;
  748.    }
  749.    if (ldata[0] != RZ_BMAGIC)
  750.    {
  751.       fprintf(stderr,"tabu: tape is not a tabu disk image backup\n");
  752.       tp_close();
  753.       return;
  754.    }
  755.    fprintf(stderr,"tabu: backup date = %s\n",&(bdata[4]));
  756.    if (dk_init())
  757.    {
  758.       tp_close();
  759.       return;
  760.    }
  761.    tpsc.scsi_Actual = RZ_BYTS * RZ_BLKS;
  762.    for (size = 0; tpsc.scsi_Actual == (RZ_BYTS * RZ_BLKS);
  763.       size += tpsc.scsi_Actual)
  764.    {
  765.       if (tp_read(RZ_BLKS)) break;
  766.       if (dk_write((size / RZ_BYTS),(tpsc.scsi_Actual / RZ_BYTS))) break;
  767.    }
  768.    fprintf(stderr,"tabu: restore bytes = %d\n",size);
  769.    dk_close();
  770.    tp_close();
  771. }
  772. /* ---------------------------------------------------------------------- */
  773. long bk_write(struct FileInfoBlock *fib)
  774. {
  775.    long recd;
  776.    long remn;
  777.    long totl;
  778.    struct FileHandle *fhndl;
  779.  
  780.    if ((fhndl = Open(fib->fib_FileName,MODE_OLDFILE)) == NULL)
  781.    {
  782.       fprintf(stderr,"tabu: file Open error = %d\n",IoErr());
  783.       return 1;
  784.    }
  785.    totl = 0;
  786.    remn = (RZ_BYTS * RZ_BLKS) - (long)(dptr - bdata);
  787.    while ((recd = Read(fhndl,(char *)dptr,remn)) == remn)
  788.    {
  789.       dptr = bdata;
  790.       if (tp_write(RZ_BLKS))
  791.       {
  792.          Close(fhndl);
  793.          return 1;
  794.       }
  795.       totl += recd;
  796.       remn = (RZ_BYTS * RZ_BLKS);
  797.    }
  798.    if (recd != 0)
  799.    {
  800.       if (recd > 0)
  801.       {
  802.          totl += recd;
  803.          for (; (recd % RZ_BYTS) != 0; recd++)
  804.             dptr[recd] = 0x00;
  805.          dptr += recd;
  806.          if (dptr >= (bdata + (RZ_BLKS * RZ_BYTS)))
  807.          {
  808.             dptr = bdata;
  809.             if (tp_write(RZ_BLKS))
  810.             {
  811.                Close(fhndl);
  812.                return 1;
  813.             }
  814.          }
  815.       }
  816.       else
  817.       {
  818.          fprintf(stderr,"tabu: file Read error = %d\n",IoErr());
  819.          Close(fhndl);
  820.          return 1;
  821.       }
  822.    }
  823.    Close(fhndl);
  824.    if (totl != fib->fib_Size)
  825.    {
  826.       fprintf(stderr,"tabu: size error, expected %d, received %d\n",
  827.          fib->fib_Size,totl);
  828.       return 1;
  829.    }
  830.    return 0;
  831. }
  832. /* ---------------------------------------------------------------------- */
  833. long dk_capacity()
  834. {
  835.    dksc.scsi_Data = data;
  836.    dksc.scsi_Length = 8;
  837.    dksc.scsi_Command = dkcmd;
  838.    dksc.scsi_CmdLength = 10;
  839.    dksc.scsi_Flags = SCSIF_READ;
  840.    dkcmd[0] = 0x25;   /* read capacity command */
  841.    dkcmd[1] = 0x00;
  842.    dkcmd[2] = 0x00;
  843.    dkcmd[3] = 0x00;
  844.    dkcmd[4] = 0x00;
  845.    dkcmd[5] = 0x00;
  846.    dkcmd[6] = 0x00;
  847.    dkcmd[7] = 0x00;
  848.    dkcmd[8] = 0x00;
  849.    dkcmd[9] = 0x00;
  850.    if (DoIO((RZ_IOR *)&dkior))
  851.    {
  852.       fprintf(stderr,"tabu: dk_capacity, DoIO error = %d\n",dkior.io_Error);
  853.       return 1;
  854.    }
  855.    return 0;
  856. }
  857. /* ---------------------------------------------------------------------- */
  858. long dk_close()
  859. {
  860.    CloseDevice((RZ_IOR *)&dkior);
  861. }
  862. /* ---------------------------------------------------------------------- */
  863. long dk_init()
  864. {
  865.    long i;
  866.  
  867.    if (FindName(&SysBase->DeviceList,scsi) == NULL)
  868.    {
  869.       fprintf(stderr,"tabu: Device %s not found\n",scsi);
  870.       return 1;
  871.    }
  872.    dkmp.mp_SigTask = (struct Task *)FindTask(NULL);
  873.    NewList(&dkmp.mp_MsgList);
  874.    if (OpenDevice(scsi,disk,(RZ_IOR *)&dkior,0))
  875.    {
  876.       fprintf(stderr,"tabu: Device %s open failed.\n",scsi);
  877.       return 1;
  878.    }
  879.    dkior.io_Command = HD_SCSICMD;
  880.    dkior.io_Length = sizeof(dksc);
  881.    dkior.io_Data = (APTR) &dksc;
  882.    return 0;
  883. }
  884. /* ---------------------------------------------------------------------- */
  885. long dk_read(long lba,long len)
  886. {
  887.    dksc.scsi_Data = data;
  888.    dksc.scsi_Length = len * RZ_BYTS;
  889.    dksc.scsi_Command = dkcmd;
  890.    dksc.scsi_CmdLength = 6;
  891.    dksc.scsi_Flags = SCSIF_READ;
  892.    dkcmd[0] = 0x08;   /* read command */
  893.    dkcmd[1] = (lba & 0x1f0000) >> 16;   /* MSB logical block address */
  894.    dkcmd[2] = (lba & 0xff00) >> 8;      /*     logical block address */
  895.    dkcmd[3] = lba & 0xff;               /* LSB logical block address */
  896.    dkcmd[4] = len & 0xff;               /* number of blocks */
  897.    dkcmd[5] = 0x00;
  898.    if (DoIO((RZ_IOR *)&dkior))
  899.    {
  900.       fprintf(stderr,"tabu: dk_read, DoIO error = %d\n",dkior.io_Error);
  901.       return 1;
  902.    }
  903.    return 0;
  904. }
  905. /* ---------------------------------------------------------------------- */
  906. long dk_write(long lba,long len)
  907. {
  908.    dksc.scsi_Data = data;
  909.    dksc.scsi_Length = len * RZ_BYTS;
  910.    dksc.scsi_Command = dkcmd;
  911.    dksc.scsi_CmdLength = 6;
  912.    dksc.scsi_Flags = SCSIF_WRITE;
  913.    dkcmd[0] = 0x0a;                     /* write command */
  914.    dkcmd[1] = (lba & 0x1f0000) >> 16;   /* MSB logical block address */
  915.    dkcmd[2] = (lba & 0xff00) >> 8;      /*     logical block address */
  916.    dkcmd[3] = lba & 0xff;               /* LSB logical block address */
  917.    dkcmd[4] = len & 0xff;               /* number of blocks */
  918.    dkcmd[5] = 0x00;
  919.    if (DoIO((RZ_IOR *)&dkior))
  920.    {
  921.       fprintf(stderr,"tabu: dk_write, DoIO error = %d\n",dkior.io_Error);
  922.       return 1;
  923.    }
  924.    return 0;
  925. }
  926. /* ---------------------------------------------------------------------- */
  927. void tmconv(struct DateStamp *date,char *dstr,char *tstr)
  928. {
  929.    long timer;
  930.    struct tm *tptr;
  931.  
  932.    timer = (date->ds_Days + 2922) * 86400;
  933.    timer += date->ds_Minute * 60;
  934.    timer += date->ds_Tick / TICKS_PER_SECOND;
  935.    tptr = localtime((time_t *)(&timer));
  936.    switch (tptr->tm_mon)
  937.    {
  938.       case 0:
  939.          strcpy(tstr,"Jan");
  940.          break;
  941.       case 1:
  942.          strcpy(tstr,"Feb");
  943.          break;
  944.       case 2:
  945.          strcpy(tstr,"Mar");
  946.          break;
  947.       case 3:
  948.          strcpy(tstr,"Apr");
  949.          break;
  950.       case 4:
  951.          strcpy(tstr,"May");
  952.          break;
  953.       case 5:
  954.          strcpy(tstr,"Jun");
  955.          break;
  956.       case 6:
  957.          strcpy(tstr,"Jul");
  958.          break;
  959.       case 7:
  960.          strcpy(tstr,"Aug");
  961.          break;
  962.       case 8:
  963.          strcpy(tstr,"Sep");
  964.          break;
  965.       case 9:
  966.          strcpy(tstr,"Oct");
  967.          break;
  968.       case 10:
  969.          strcpy(tstr,"Nov");
  970.          break;
  971.       case 11:
  972.          strcpy(tstr,"Dec");
  973.          break;
  974.    }
  975.    sprintf(dstr,"%02d-%s-%02d",tptr->tm_mday,tstr,tptr->tm_year);
  976.    sprintf(tstr,"%02d:%02d:%02d",tptr->tm_hour,tptr->tm_min,tptr->tm_sec);
  977.    return;
  978. }
  979. /* ---------------------------------------------------------------------- */
  980. long tp_close()
  981. {
  982.    tp_rewind();
  983.    CloseDevice((RZ_IOR *)&tpior);
  984.    fprintf(stderr,"tabu finished, Press RETURN when ready.\n");
  985.    getchar();
  986.    exit(1);
  987. }
  988. /* ---------------------------------------------------------------------- */
  989. long tp_eof()
  990. {
  991.    tpsc.scsi_Data = NULL;
  992.    tpsc.scsi_Length = 0;
  993.    tpsc.scsi_Command = tpcmd;
  994.    tpsc.scsi_CmdLength = 6;
  995.    tpsc.scsi_Flags = 0;
  996.    tpcmd[0] = 0x10;                         /* write filemark command */
  997.    tpcmd[1] = 0;
  998.    tpcmd[2] = 0;                            /* MSB Number of filemarks */
  999.    tpcmd[3] = 0;                            /*     Number of filemarks */
  1000.    tpcmd[4] = 2;                            /* LSB Number of filemarks */
  1001.    tpcmd[5] = 0;
  1002.    if (DoIO((RZ_IOR *)&tpior))
  1003.    {
  1004.       fprintf(stderr,"tabu: tp_eof, DoIO error = %d\n",tpior.io_Error);
  1005.       return 1;
  1006.    }
  1007.    return 0;
  1008. }
  1009. /* ---------------------------------------------------------------------- */
  1010. long tp_init()
  1011. {
  1012.    if (FindName(&SysBase->DeviceList,scsi) == NULL)
  1013.    {
  1014.       fprintf(stderr,"tabu: Device %s not found\n",scsi);
  1015.       return 1;
  1016.    }
  1017.    tpmp.mp_SigTask = (struct Task *)FindTask(NULL);
  1018.    NewList(&tpmp.mp_MsgList);
  1019.    if (OpenDevice(scsi,tape,(RZ_IOR *)&tpior,0))
  1020.    {
  1021.       fprintf(stderr,"tabu: Device %s open failed.\n",scsi);
  1022.       return 1;
  1023.    }
  1024.    tpior.io_Command = HD_SCSICMD;
  1025.    tpior.io_Length = sizeof(tpsc);
  1026.    tpior.io_Data = (APTR) &tpsc;
  1027.    if (tp_sense())
  1028.    {
  1029.       tp_close();
  1030.       return 1;
  1031.    }
  1032.    if (bdata[8] & 0x40)
  1033.    {
  1034.       fprintf(stderr,"tabu: No tape in drive!\n");
  1035.       return 1;
  1036.    }
  1037.    if (tp_rewind())
  1038.    {
  1039.       tp_close();
  1040.       return 1;
  1041.    }
  1042.    return 0;
  1043. }
  1044. /* ---------------------------------------------------------------------- */
  1045. long tp_read(long len)
  1046. {
  1047.    tpsc.scsi_Data = data;
  1048.    tpsc.scsi_Length = len * RZ_BYTS;
  1049.    tpsc.scsi_Command = tpcmd;
  1050.    tpsc.scsi_CmdLength = 6;
  1051.    tpsc.scsi_Flags = SCSIF_READ;
  1052.    tpcmd[0] = 0x08;   /* read command */
  1053.    tpcmd[1] = 0x01;
  1054.    tpcmd[2] = (len & 0xff0000) >> 16;   /* MSB number of blocks */
  1055.    tpcmd[3] = (len & 0xff00) >> 8;      /*     number of blocks */
  1056.    tpcmd[4] = len & 0xff;               /* LSB number of blocks */
  1057.    tpcmd[5] = 0x00;
  1058.    if (DoIO((RZ_IOR *)&tpior))
  1059.    {
  1060.       fprintf(stderr,"tabu: tp_read, DoIO error = %d\n",tpior.io_Error);
  1061.       return 1;
  1062.    }
  1063.    return 0;
  1064. }
  1065. /* ---------------------------------------------------------------------- */
  1066. long tp_rewind()
  1067. {
  1068.    tpsc.scsi_Data = NULL;
  1069.    tpsc.scsi_Length = 0;
  1070.    tpsc.scsi_Command = tpcmd;
  1071.    tpsc.scsi_CmdLength = 6;
  1072.    tpsc.scsi_Flags = 0;
  1073.    tpcmd[0] = 0x01;                         /* rewind command */
  1074.    tpcmd[1] = 0;
  1075.    tpcmd[2] = 0;
  1076.    tpcmd[3] = 0;
  1077.    tpcmd[4] = 0;
  1078.    tpcmd[5] = 0;
  1079.    if (DoIO((RZ_IOR *)&tpior))
  1080.    {
  1081.       fprintf(stderr,"tabu: tp_rewind, DoIO error = %d\n",tpior.io_Error);
  1082.       return 1;
  1083.    }
  1084.    return 0;
  1085. }
  1086. /* ---------------------------------------------------------------------- */
  1087. long tp_sense()
  1088. {
  1089.    tpsc.scsi_Data = data;
  1090.    tpsc.scsi_Length = 14;
  1091.    tpsc.scsi_Command = tpcmd;
  1092.    tpsc.scsi_CmdLength = 6;
  1093.    tpsc.scsi_Flags = SCSIF_READ;
  1094.    tpcmd[0] = 0x03;   /* sense command */
  1095.    tpcmd[1] = 0x00;
  1096.    tpcmd[2] = 0x00;
  1097.    tpcmd[3] = 0x00;
  1098.    tpcmd[4] = 0x0e;   /* number of sense bytes to fetch */
  1099.    tpcmd[5] = 0x00;
  1100.    if (DoIO((RZ_IOR *)&tpior))
  1101.    {
  1102.       fprintf(stderr,"tabu: tp_sense, DoIO error = %d\n",tpior.io_Error);
  1103.       return 1;
  1104.    }
  1105.    return 0;
  1106. }
  1107. /* ---------------------------------------------------------------------- */
  1108. long tp_write(long len)
  1109. {
  1110.    tpsc.scsi_Data = data;
  1111.    tpsc.scsi_Length = len * RZ_BYTS;
  1112.    tpsc.scsi_Command = tpcmd;
  1113.    tpsc.scsi_CmdLength = 6;
  1114.    tpsc.scsi_Flags = SCSIF_WRITE;
  1115.    tpcmd[0] = 0x0a;                         /* write command */
  1116.    tpcmd[1] = 0x01;
  1117.    tpcmd[2] = (len & 0xff0000) >> 16;   /* MSB number of blocks */
  1118.    tpcmd[3] = (len & 0xff00) >> 8;      /*     number of blocks */
  1119.    tpcmd[4] = len & 0xff;               /* LSB number of blocks */
  1120.    tpcmd[5] = 0x00;
  1121.    if (DoIO((RZ_IOR *)&tpior))
  1122.    {
  1123.       fprintf(stderr,"tabu: tp_write, DoIO error = %d\n",tpior.io_Error);
  1124.       return 1;
  1125.    }
  1126.    return 0;
  1127. }
  1128. /* end of code ---------------------------------------------------------- */
  1129.